home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / mxcode / sbdsp103 / voc.pas < prev   
Pascal/Delphi Source File  |  1994-09-10  |  12KB  |  312 lines

  1. {       SBDSP is Copyright 1994 by Ethan Brodsky.  All rights reserved.      }
  2. unit VOC;
  3.     interface
  4.         const
  5.             EndBlockNum            = 0;
  6.             VoiceBlockNum          = 1;
  7.             VoiceContinueBlockNum  = 2;
  8.             SilenceBlockNum        = 3;
  9.             MarkerBlockNum         = 4;
  10.             MessageBlockNum        = 5;
  11.             RepeatBlockNum         = 6;
  12.             RepeatEndBlockNum      = 7;
  13.             ExtendedInfoBlockNum   = 8;
  14.             NewVoiceBlockNum       = 9;
  15.             BlockNames : array[0..9] of string =
  16.                 (
  17.                  'Terminator',
  18.                  'Voice Data',
  19.                  'Voice Continuation',
  20.                  'Silence',
  21.                  'Marker',
  22.                  'Message',
  23.                  'Repeat Loop',
  24.                  'End Repeat Loop',
  25.                  'Extended Info',
  26.                  'New Voice Data'
  27.                 );
  28.             {Used in block type 1 and 8}
  29.             Unpacked8  = 0; {8 bit (Uncompressed)}
  30.             Packed4    = 1; {4 bit}
  31.             Packed26   = 2; {2.6 bit}
  32.             Packed2    = 3; {2 bit}
  33.             PackingNames : array[0..10] of string =
  34.                 (
  35.                  '8 bit unpacked',
  36.                  '4 bit packed',
  37.                  '2.6 bit packed',
  38.                  '2 bit packed',
  39.                  '1 channel multi',
  40.                  '2 channel multi',
  41.                  '3 channel multi',
  42.                  '4 channel multi',
  43.                  '5 channel multi',
  44.                  '6 channel multi',
  45.                  '7 channel multi'
  46.                 );
  47.             {Used in block type 9}
  48.             Uncompressed8     = $0000;
  49.             Compressed4       = $0001;
  50.             Compressed26      = $0002;
  51.             Compressed2       = $0003;
  52.             Uncompressed16    = $0004;
  53.             CompressedALAW    = $0006;
  54.             CompressedMULAW   = $0007;
  55.             CompressedADPCM   = $0200; {Why couldn't they make this $0008?}
  56.             CompressionNames : array[0..7] of string =
  57.                 (
  58.                     '8 bit uncompressed',
  59.                     '4 bit compressed',
  60.                     '2.6 bit compressed',
  61.                     '2 bit compressed',
  62.                     '16 bit uncompressed',
  63.                     '',
  64.                     'ALAW compressed',
  65.                     'MULAW compressed'
  66.                 );
  67.             ExtendedMono   = 0;
  68.             ExtendedStereo = 1;
  69.             ExtendedModeNames : array[0..1] of string = ('Mono', 'Stereo');
  70.  
  71.             NewMono   = 1;      {This is Creative Labs' fault}
  72.             NewStereo = 2;      {Blame it on Creative Labs}
  73.             NewModeNames : array[1..2] of string = ('Mono', 'Stereo');
  74.         type
  75.             PSound = ^TSound;
  76.             TSound = array[0..65520] of byte;
  77.  
  78.             PVOCHeader = ^TVOCHeader;
  79.             TVOCHeader = array[1..26] of byte;
  80.  
  81.             TripleByte = array[1..3] of byte;
  82.  
  83.             PBlock = ^TBlock;
  84.             TBlock =
  85.                 record
  86.                     BlockType: byte;
  87.                     BlockLength: TripleByte;
  88.                 end;
  89.  
  90.             PEndBlock = ^TEndBlock;
  91.             TEndBlock =
  92.                 record
  93.                     BlockType : byte;
  94.                 end;
  95.  
  96.             PVoiceBlock = ^TVoiceBlock;
  97.             TVoiceBlock =
  98.                 record
  99.                     BlockType : byte;
  100.                     BlockLength : TripleByte;
  101.                     SR : byte;
  102.                     Packing : byte;
  103.                     Data : array[0..65520] of byte;
  104.                 end;
  105.  
  106.             PVoiceContinueBlock = ^TVoiceContinueBlock;
  107.             TVoiceContinueBlock =
  108.                 record
  109.                     BlockType : byte;
  110.                     BlockLength : TripleByte;
  111.                     Data : array[0..65520] of byte;
  112.                 end;
  113.  
  114.             PSilenceBlock = ^TSilenceBlock;
  115.             TSilenceBlock =
  116.                 record
  117.                     BlockType : byte;
  118.                     BlockLength : TripleByte;
  119.                     Duration : word;
  120.                     SR : byte;
  121.                 end;
  122.  
  123.             PMarkerBlock = ^TMarkerBlock;
  124.             TMarkerBlock =
  125.                 record
  126.                     BlockType : byte;
  127.                     BlockLength : TripleByte;
  128.                     Marker : word;
  129.                 end;
  130.  
  131.             PMessageBlock = ^TMessageBlock;
  132.             TMessageBlock =
  133.                 record
  134.                     BlockType : byte;
  135.                     BlockLength : TripleByte;
  136.                     Data: array[0..65520] of char;
  137.                 end;
  138.  
  139.             PRepeatBlock = ^TRepeatBlock;
  140.             TRepeatBlock =
  141.                 record
  142.                     BlockType : byte;
  143.                     BlockLength : TripleByte;
  144.                     Count: word;
  145.                 end;
  146.  
  147.             PRepeatEndBlock = ^TRepeatEndBlock;
  148.             TRepeatEndBlock =
  149.                 record
  150.                     BlockType : byte;
  151.                     BlockLength : TripleByte;
  152.                 end;
  153.             PExtendedInfoBlock = ^TExtendedInfoBlock;
  154.             TExtendedInfoBlock =
  155.                 record
  156.                     BlockType : byte;
  157.                     BlockLength : TripleByte;
  158.                     ExtendedSR : word;
  159.                     Packing : byte;
  160.                     Mode : byte; {0 = mono, 1 = stereo}
  161.                 end;
  162.             PNewVoiceBlock = ^TNewVoiceBlock;
  163.             TNewVoiceBlock =
  164.                 record
  165.                     BlockType : byte;
  166.                     BlockLength : TripleByte;
  167.                     SamplingRate : word; {HZ}
  168.                     Dummy1 : array[1..2] of byte;
  169.                     BitsPerSample : byte; {Uncompressed bits per sample}
  170.                     Mode : byte; {1 = mono, 2 = stereo}
  171.                     Compression: word;
  172.                     Dummy2 : array[1..4] of byte;
  173.                     Data : array[0..64000] of byte;
  174.                 end;
  175.         function TripleByteToLongint(TB: TripleByte): LongInt;
  176.         function GetSamplingRate(SR: byte): LongInt;
  177.         function GetSRByte(SamplingRate: word): byte;
  178.         function GetExtendedSamplingRate(ExtendedSR: word; Mode: byte): LongInt;
  179.         function BlockSize(Block: PBlock): LongInt;
  180.         procedure IncrementPtr(var P: pointer; Count: word);
  181.         function FindNextBlock(Block: PBlock): PBlock;
  182.         function LoadVOCFile(FileName: string; var Sound: PSound): LongInt;
  183.     implementation
  184.         uses
  185.             Mem;
  186.         function TripleByteToLongint(TB: TripleByte): LongInt;
  187.             begin
  188.                 TripleByteToLongint := LongInt(TB[1]) + LongInt(TB[2]) SHL 8 + LongInt(TB[3]) SHL 16;
  189.             end;
  190.         function GetSamplingRate(SR: byte): LongInt;
  191.             begin
  192.                 GetSamplingRate := -1000000 div (SR - 256);
  193.             end;
  194.         function GetSRByte(SamplingRate: word): byte;
  195.             begin
  196.                 GetSRByte := 256-(1000000 div SamplingRate);
  197.             end;
  198.         function GetExtendedSamplingRate(ExtendedSR: word; Mode: byte): LongInt;
  199.             begin
  200.                 case Mode
  201.                     of
  202.                         ExtendedMono:
  203.                             GetExtendedSamplingRate := -256000000 div (ExtendedSR-65536);
  204.                         ExtendedStereo:
  205.                             GetExtendedSamplingRate := (-256000000 div (ExtendedSR-65536)) div 2;
  206.                     end;
  207.             end;
  208.         function BlockSize(Block: PBlock): LongInt;
  209.             begin
  210.                 BlockSize := TripleByteToLongInt(Block^.BlockLength) + 4;
  211.             end;
  212.         procedure IncrementPtr(var P: pointer; Count: word);
  213.           {Easier to implement in assembly}
  214.             begin
  215.                 asm
  216.                     LES  DI, P
  217.                     MOV  BX, Count
  218.                     MOV  AX, ES:[DI]
  219.                     MOV  DX, ES:[DI+2]
  220.                     ADD  AX, BX
  221.                     CMP  AX, $000F
  222.                     JNA  @1
  223.                     MOV  BX, AX
  224.                     AND  AX, $F
  225.                     AND  BX, $FFF0
  226.                     MOV  CL, 4
  227.                     SHR  BX, CL
  228.                     ADD  DX, BX
  229.                   @1:
  230.                     MOV  ES:[DI], AX
  231.                     MOV  ES:[DI+2], DX
  232.                 end;
  233.             end;
  234.         function FindNextBlock(Block: PBlock): PBlock;
  235.             var
  236.                 NewBlock: PBlock;
  237.                 BlockSize: LongInt;
  238.             begin
  239.                 if Block^.BlockType = EndBlockNum
  240.                     then
  241.                         begin
  242.                             FindNextBlock := nil;
  243.                             Exit;
  244.                         end;
  245.                 NewBlock := Block;
  246.                 BlockSize := TripleByteToLongInt(Block^.BlockLength) + 4;
  247.                 while BlockSize > 0 do
  248.                     begin
  249.                         if BlockSize > 64000
  250.                             then
  251.                                 begin
  252.                                     IncrementPtr(pointer(NewBlock), 64000);
  253.                                     Dec(BlockSize, 64000);
  254.                                 end
  255.                             else
  256.                                 begin
  257.                                     IncrementPtr(pointer(NewBlock), BlockSize);
  258.                                     BlockSize := 0;
  259.                                 end;
  260.                     end;
  261.                 FindNextBlock := NewBlock;
  262.             end;
  263.         function LoadVOCFile(FileName: string; var Sound: PSound): LongInt;
  264.            var
  265.                 f: file;
  266.                 Dummy: Pointer;
  267.                 LeftToRead: LongInt;
  268.                 Header: PVOCHeader;
  269.             begin
  270.                 Assign(f, FileName);
  271.                 {$I-}
  272.                 Reset(f, 1);
  273.                 {$I+}
  274.                 if IOResult <> 0
  275.                     then
  276.                         begin
  277.                             LoadVOCFile := 0; {Couldn't open file}
  278.                             Exit;
  279.                         end;
  280.                 LeftToRead := FileSize(f) - SizeOf(Header^);
  281.                 LoadVOCFile := LeftToRead;
  282.                 New(Header);
  283.                 BlockRead(f, Header^, SizeOf(Header^));
  284.  
  285.                 if GetBuffer(pointer(Sound), LeftToRead) <> true
  286.                     then
  287.                         begin
  288.                             LoadVOCfile := 0; {Failed to allocate memory}
  289.                             Exit;
  290.                         end;
  291.                 Dummy := Sound;
  292.                 while LeftToRead > 0 do
  293.                     begin
  294.                         if LeftToRead < 64000
  295.                             then
  296.                                 begin
  297.                                     BlockRead(f, Dummy^, LeftToRead);
  298.                                     LeftToRead := 0;
  299.                                 end
  300.                             else
  301.                                 begin
  302.                                     BlockRead(f, Dummy^, 64000);
  303.                                     LeftToRead := LeftToRead - 64000;
  304.                                     IncrementPtr(Dummy, 64000);
  305.                                 end;
  306.                     end;
  307.                 Close(f);
  308.                 Dispose(Header);
  309.             end;
  310.     begin
  311.     end.
  312.